﻿#if MAPEDITOR

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Windows.Forms;
using Microsoft.Xna.Framework.Graphics;
using FolderData;

namespace Folder
{
    public partial class MapProperty : Form
    {
        public enum SubstanceKind
        {
            Character,
            Item,
            Terrain,
            None
        }

        static readonly int ImgWidth = 64;
        static readonly int ImgHeight = 64;

        Map _map;
        string _selectedName;
        SubstanceKind _selectedKind;
        bool _haslistView;

        public string SelectedName
        {
            get { return _selectedName; }
        }
        public SubstanceKind SelectedKind
        {
            get { return _selectedKind; }
        }
        
        public bool HasListView
        {
            get { return _haslistView; }
        }


        public MapProperty()
        {
            _map = null;
            _selectedKind = SubstanceKind.None;
            _selectedName = string.Empty;
            _haslistView = false;

            InitializeComponent();

            Terrain.TerrainDataSet ds;
            ds = new Terrain.TerrainDataSet();
            ds.IsFoldable = false;
            ds.IsVirtualGeom = true;
            ds.Kind = Terrain.TerrainKind.GATE;
            ds.Layer = Substance.LayerOrder.THIRD;
            ds.Name = "ddd";
            ds.Position = new Microsoft.Xna.Framework.Vector2(3f, 4f);
            ds.Rotation = 0f;
            Substance.DataSet d = ds;
            
//             AttributeCollection atts = TypeDescriptor.GetProperties(ds)["Name"].Attributes;
//             bool dunno = atts[typeof(BrowsableAttribute)].Equals(BrowsableAttribute.Yes);
            propertyGrid1.SelectedObject = d;
            //propertyGrid1.Refresh();
            
        }

        void MapProperty_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;
        }

        Bitmap texture2Bitmap(Texture2D t)
        {
            int[] tData = new int[t.Width * t.Height];
            t.GetData<int>(tData);
            int w = t.Width < ImgWidth ? t.Width : ImgWidth;
            int h = t.Height < ImgHeight ? t.Height : ImgHeight;
            Bitmap b = new Bitmap(w, h);
            for (int x = 0; x < w; ++x)
            {
                for (int y = 0; y < h; ++y)
                    b.SetPixel(x, y, System.Drawing.Color.FromArgb(tData[y * t.Width + x]));
            }
            return b;
        }

        /// <summary>
        /// 리소스 매니저와 작업 중인 맵의 레퍼런스를 받아
        /// 정보를 출력할 수 있도록 가공합니다.
        /// </summary>
        /// <param name="rManager">리소스 매니저</param>
        /// <param name="map">현재 작업중인 맵</param>
        public void SetData(Map map)
        {
            _map = map;
        }

        /// <summary>
        /// PropertyGridView에 보여질 물체를 선택합니다.
        /// </summary>
        /// <param name="obj"></param>
        public void Select(object obj)
        {
            propertyGrid1.SelectedObject = obj;
        }

        public void RefreshGrid()
        {
            propertyGrid1.Refresh();
        }

        public void SetListView()
        {
            //terrain
            ImageList imgList = new ImageList();
            imgList.ImageSize = new Size(ImgWidth, ImgHeight);
            imgList.ColorDepth = ColorDepth.Depth32Bit;
            int i = 0;
            foreach (Terrain t in ResourceManager.Instance.Terrains)
            {
                terrainListView.Items.Add(new ListViewItem(t.Name, i));
                imgList.Images.Add(texture2Bitmap(t.Texture));
                ++i;
            }
            terrainListView.LargeImageList = imgList;

            //character
            imgList = new ImageList();
            imgList.ImageSize = new Size(ImgWidth, ImgHeight);
            imgList.ColorDepth = ColorDepth.Depth32Bit;
            i = 0;
            foreach (Character c in ResourceManager.Instance.Characters)
            {
                characterListView.Items.Add(new ListViewItem(c.Name, i));
                imgList.Images.Add(texture2Bitmap(c.Texture));
                ++i;
            }
            characterListView.LargeImageList = imgList;

            //item
            imgList = new ImageList();
            imgList.ImageSize = new Size(ImgWidth, ImgHeight);
            imgList.ColorDepth = ColorDepth.Depth32Bit;
            i = 0;
            foreach (Item it in ResourceManager.Instance.Items)
            {
                itemListView.Items.Add(new ListViewItem(it.Name, i));
                imgList.Images.Add(texture2Bitmap(it.Texture));
                ++i;
            }
            itemListView.LargeImageList = imgList;
            
            _haslistView = true;
        }

        #region Event Handling
        private void characterListView_MouseClick(object sender, MouseEventArgs e)
        {
            propertyGrid1.SelectedObject = ResourceManager.Instance.PeekResource<Character>(characterListView.SelectedItems[0].Text);
            _selectedKind = SubstanceKind.Character;
            _selectedName = characterListView.SelectedItems[0].Text;
        }

        private void terrainListView_MouseClick(object sender, MouseEventArgs e)
        {
            propertyGrid1.SelectedObject = ResourceManager.Instance.PeekResource<Terrain>(terrainListView.SelectedItems[0].Text);
            _selectedKind = SubstanceKind.Terrain;
            _selectedName = terrainListView.SelectedItems[0].Text;
        }

        private void itemListView_MouseClick(object sender, MouseEventArgs e)
        {
            propertyGrid1.SelectedObject = ResourceManager.Instance.PeekResource<Item>(itemListView.SelectedItems[0].Text);
            _selectedKind = SubstanceKind.Item;
            _selectedName = itemListView.SelectedItems[0].Text;
        }


        private bool isIdDuplicate(Substance.DataSet dataset)
        {
            foreach (var i in _map.CharacterDatas)
                if (dataset != i && dataset.id == i.id)
                    return true;
            foreach (var i in _map.TerrainDatas)
                if (dataset != i && dataset.id == i.id)
                    return true;
            foreach (var i in _map.ItemDatas)
                if (dataset != i && dataset.id == i.id)
                    return true;

            return false;
        }

        private void propertyGrid1_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
        {
            Type t = (s as PropertyGrid).SelectedObject.GetType();

            //id가 겹쳤을 때를 위한 임시조치
            var dataset = (s as PropertyGrid).SelectedObject as Substance.DataSet;
            if (isIdDuplicate(dataset))
            {
                DialogResult result = MessageBox.Show("ID가 중복됩니다.", "Folder Map Editor", MessageBoxButtons.OK, MessageBoxIcon.Warning);

                //아이디가 겹칠 경우 새로운 아이디를 부여한다
                int postFixCount = 0;
                while (isIdDuplicate(dataset))
                {
                    dataset.id = dataset.Name + "_" + postFixCount;
                    postFixCount++;
                }
                return;
            }

            if (t == typeof(Character.CharacterDataSet))
            {
                Character.CharacterDataSet ds = (s as PropertyGrid).SelectedObject as Character.CharacterDataSet;
                (ds.Tag as Character).SetDatas(ds);
            }
            else if (t == typeof(Terrain.TerrainDataSet))
            {
                Terrain.TerrainDataSet ds = (s as PropertyGrid).SelectedObject as Terrain.TerrainDataSet;
                (ds.Tag as Terrain).SetDatas(ds);
            }
            else if (t == typeof(Item.ItemDataSet))
            {
                Item.ItemDataSet ds = (s as PropertyGrid).SelectedObject as Item.ItemDataSet;
                (ds.Tag as Item).SetDatas(ds);
            }
            else if (t == typeof(MapEditor.PosDesc))
            {
                //avoid exception.
            }
            else
                throw new Exception("예상치 못한 상황: PropertyGrid에서 변경가능할 때는 DataSet이 선택되었을 때일 뿐일 텐데");
            
            //Layer가 바뀌면 물체를 넣었다가 뺀다.
            if (e.OldValue.GetType() == typeof(Substance.LayerOrder))
            {
                Substance.DataSet dats = (s as PropertyGrid).SelectedObject as Substance.DataSet;
                Substance.LayerOrder oldLayer = (Substance.LayerOrder)e.OldValue;
                if (dats.Layer != oldLayer)
                {
                    dats.Tag.Layer = oldLayer;
                    _map.RemoveSubstance(dats.Tag, dats.id);
                    dats.Tag.Layer = dats.Layer;
                    _map.AddSubstance(dats.Tag, dats.id);
                }
            }
            _map.IsSaved = false;
        }
        #endregion

        public bool IsActivated = false;
        private void MapProperty_Activated(object sender, EventArgs e)
        {
            IsActivated = true;
        }

        private void MapProperty_Deactivate(object sender, EventArgs e)
        {
            IsActivated = false;
        }
        

    }
}

#endif